<?php

/**
 * Main project class.
 *
 * Handle all requess and run upplication with model, view and controller
 * 
 * @author Eugene I. Nezhuta
 * @copyright (c) 2009 - 2010 NeLab <www.ne-lab.com>
 */

class Core {
	
	/**
	 * Main core method.
     * 
     * Calls all necssary methods to run the application
	 */
	public function run() {
		$controller = $this->_getController();
		$model = $this->_getModel($controller);
		$action = $this->_getAction();
		$this->_execute($controller, $action, $model);
	}

	/**
	 * Get requested controller.
     * 
     * Takes controller name from request, if there is no controller name, takes 
     * default from config, makes volid controller path and requires necessary class
	 *
     * @return string
	 */
	protected function _getController() {
		$controller = (!empty($_GET['cont']) ? $_GET['cont'] : Config::$defaultController);
		$controllerName = $this->_setValidControllerName($controller);
		$controllerPath = $this->_setValidControllerPath($controllerName);
		if(!file_exists($controllerPath)) {
			throw new ExceptionCore('404 Controller not found!');
		}
		if(!is_readable($controllerPath)) {
			throw new ExceptionCore('System can not execute controller!');
		}
		require_once $controllerPath;
		return $controllerName;
	}

    /**
     * Makes valid model name and requires necessary model class
     *
     * @param string $controller valid controller name
     * @return string
     */
	protected function _getModel($controller) {
		$modelName = str_replace('Controller', 'Model', $controller);
		$modelPath = Config::$path . '/' . Config::$modelsDir . '/' . $modelName . Config::$controllerExt;
		if(!file_exists($modelPath)) {
			throw new ExceptionCore("Model <b>" . $modelName . " does not exists.");
		}
		require_once $modelPath;
		return $modelName;
	}

    /**
     * Takes action from request.
     * 
     * If no action specified takes default action from config
     *
     * @return string
     */
	protected function _getAction() {
		$action = (!empty($_GET['act']) ? $_GET['act'] : Config::$defaultAction);
		return $action . 'Action';
	}

    /**
     * Takes controller name, model name and action
     *
     * Makes controller and model objects, then excute action
     *
     * @param string $controller
     * @param string $action
     * @param string $model
     */
	protected function _execute($controller, $action, $model) {
		$controller = new $controller(new $model);
		if(!method_exists($controller, $action)) {
			throw new ExceptionCore('404 Page not found');
		}
		if(!is_callable(array($controller, $action))) {
				throw new ExceptionCore('Failed on executing command!');
		}
		$controller->$action();
	}

    /**
     * Makes valid controller name
     *
     * @param string $controllerName
     * @return string
     */
	protected function _setValidControllerName($controllerName) {
		return ucfirst($controllerName) . 'Controller';
	}

    /**
     * Makes valid controller path
     *
     * @param string $controllerName
     * @return string
     */
	protected function _setValidControllerPath($controllerName) {
		return Config::$path . '/' . Config::$controllersDir . '/' . $controllerName . Config::$controllerExt;
		
	}
}